﻿using FluentMigrator;
using System;

namespace RockBus.Migrations.Version1_0
{
    [Migration(4)]
    public class M0004CreateMessageTables : Migration
    {
        public override void Up()
        {
            Create.Table("MessageBuffer")
                .WithColumn("DbId").AsInt64().NotNullable()
                .WithColumn("Id").AsString(255).NotNullable()
                .WithColumn("SequenceNumber").AsInt64().NotNullable()
                .WithColumn("MessageValidityDurationSecs").AsInt64().NotNullable()
                .WithColumn("MaxMessageCount").AsInt64().NotNullable();
            Create.PrimaryKey("PK_MessageBuffer").OnTable("MessageBuffer").Column("DbId");
            Create.Index("IX_MessageBuffer_Name").OnTable("MessageBuffer")
                .OnColumn("Id").Unique();

            Create.Table("Message")
                .WithColumn("Id").AsInt64().Identity().NotNullable()
                .WithColumn("PartCount").AsInt32().NotNullable()
                .WithColumn("Size").AsInt32().NotNullable()
                .WithColumn("CorrelationId").AsString(100).NotNullable()
                .WithColumn("Action").AsString(255).NotNullable()
                .WithColumn("ReceiveTime").AsDateTime().NotNullable()
                .WithColumn("ReceiveAddress").AsString(int.MaxValue).NotNullable()
                .WithColumn("CreateTime").AsDateTime().NotNullable();
            Create.PrimaryKey("PK_Message").OnTable("Message").Column("Id");

            Create.Table("MessageProcessingState")
               .WithColumn("Id").AsByte().NotNullable()
               .WithColumn("Name").AsString(50).NotNullable();
            Create.PrimaryKey("PK_MessageProcessingState").OnTable("MessageProcessingState").Column("Id");

            Insert.IntoTable("MessageProcessingState").Row(new { Id = 0, Name = "Receiving" });
            Insert.IntoTable("MessageProcessingState").Row(new { Id = 1, Name = "Pending" });
            Insert.IntoTable("MessageProcessingState").Row(new { Id = 2, Name = "Delivering" });
            Insert.IntoTable("MessageProcessingState").Row(new { Id = 3, Name = "Delivered" });
            Insert.IntoTable("MessageProcessingState").Row(new { Id = 4, Name = "Faulted" });
            Insert.IntoTable("MessageProcessingState").Row(new { Id = 5, Name = "Terminated" });

            Create.Table("MessagePart")
                .WithColumn("Id").AsInt64().Identity().NotNullable()
                .WithColumn("MessageId").AsInt64().NotNullable()
                .WithColumn("PartIndex").AsInt32().NotNullable()
                .WithColumn("Body").AsBinary(int.MaxValue).NotNullable()
                .WithColumn("Size").AsInt32().NotNullable();
            Create.PrimaryKey("PK_MessagePart").OnTable("MessagePart").Column("Id");
            Create.Index("IX_MessagePart_MessageId").OnTable("MessagePart").OnColumn("MessageId").Ascending();

            Create.Table("MessageBuffer_Message")
                .WithColumn("BufferDbId").AsInt64().NotNullable()
                .WithColumn("MessageId").AsInt64().NotNullable()
                .WithColumn("InsertTime").AsDateTime().NotNullable()
                .WithColumn("ExpirationTime").AsDateTime().NotNullable()
                .WithColumn("SequenceNumber").AsInt64().NotNullable();
            Create.PrimaryKey("PK_MessageBuffer_Message").OnTable("MessageBuffer_Message")
                .Columns(new string[] { "BufferDbId", "MessageId" });

            Create.Table("QueueEntry")
               .WithColumn("Id").AsInt64().Identity().NotNullable()
               .WithColumn("MessageId").AsInt64().NotNullable()
               .WithColumn("RoutingHeader").AsBinary(int.MaxValue).NotNullable()
               .WithColumn("Priority").AsInt32().NotNullable()
               .WithColumn("OrderedDelivery").AsBoolean().NotNullable()
               .WithColumn("ReceiverMachineName").AsString(255).NotNullable()
               .WithColumn("ReceiverProcessId").AsInt32().NotNullable()
               .WithColumn("ReceiverAppDomainId").AsInt32().NotNullable()
               .WithColumn("EnqueueTime").AsDateTime().NotNullable()
               .WithColumn("ExpirationTime").AsDateTime().Nullable()
               .WithColumn("StateId").AsByte().NotNullable()
               .WithColumn("MachineName").AsString(255).Nullable()
               .WithColumn("ProcessId").AsInt32().Nullable()
               .WithColumn("ProcessorId").AsString(100).Nullable()
               .WithColumn("BatchId").AsGuid().Nullable()
               .WithColumn("DequeueTime").AsDateTime().Nullable()
               .WithColumn("DequeueAttemptCount").AsInt32().NotNullable()
               .WithColumn("DeliveryTime").AsDateTime().Nullable()
               .WithColumn("DeliveryAttemptCount").AsInt32().NotNullable()
               .WithColumn("DeliveryAttemptIntervalSecs").AsInt64().NotNullable()
               .WithColumn("MaxDeliveryAttemptCount").AsInt32().NotNullable()
               .WithColumn("IsResponse").AsBoolean().NotNullable()
               .WithColumn("ErrorMessage").AsString(int.MaxValue).Nullable();
            Create.PrimaryKey("PK_Delivery").OnTable("QueueEntry").Column("Id");
            Create.Index("IX_QueueEntry_BatchId").OnTable("QueueEntry").OnColumn("BatchId").Ascending();
            Create.Index("IX_QueueEntry_MessageId").OnTable("QueueEntry").OnColumn("MessageId").Ascending();
            IfDatabase("SqlServer").
                Execute.Sql("ALTER TABLE [dbo].[QueueEntry] SET (LOCK_ESCALATION = DISABLE)");

            Create.ForeignKey("FK_MessageBuffer_Message_Message")
                .FromTable("MessageBuffer_Message").ForeignColumn("MessageId")
                .ToTable("Message").PrimaryColumn("Id");

            Create.ForeignKey("FK_MessageBuffer_Message_MessageBuffer")
                .FromTable("MessageBuffer_Message").ForeignColumn("BufferDbId")
                .ToTable("MessageBuffer").PrimaryColumn("DbId");

            Create.ForeignKey("FK_MessagePart_Message")
                .FromTable("MessagePart").ForeignColumn("MessageId")
                .ToTable("Message").PrimaryColumn("Id");

            Create.ForeignKey("FK_QueueEntry_Message")
               .FromTable("QueueEntry").ForeignColumn("MessageId")
               .ToTable("Message").PrimaryColumn("Id");

            Create.ForeignKey("FK_QueueEntry_MessageProcessingState1")
               .FromTable("QueueEntry").ForeignColumn("StateId")
               .ToTable("MessageProcessingState").PrimaryColumn("Id");
        }

        public override void Down()
        {
            throw new NotImplementedException();
        }
    }
}